/*
 * Copyright (C) 2010,2011  Paulo Cesar Pereira de Andrade.
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Authors:
 *	Paulo Cesar Pereira de Andrade
 */

/*
 * Prototypes
 */
#if PROTO
static void
cp_signbit_cp(c_t *u, c_t *v, eint32_t m);

static void
cp_signbit_sp(c_t *u, s_t *v, eint32_t m);

static void
cp_signbit_ip(c_t *u, i_t *v, eint32_t m);

static void
cp_signbit_lp(c_t *u, l_t *v, eint32_t m);

static void
cp_signbit_fp(c_t *u, f_t *v, eint32_t m);

static void
cp_signbit_dp(c_t *u, d_t *v, eint32_t m);

static void
cp_signbit_vo(c_t *u, vo_t *v, eint32_t m);
#endif

/*
 * Implementation
 */
#if CODE
void
evector_signbit(evector_t *v, etype_t t)
{
    eint32_t	 l;
    evector_t	*r;
    v_enter();

    v_check(1);
    l = v->length;
    r = create(v, t_int8);
    switch (t) {
	case t_uint8:	case t_uint16:	case t_uint32:	case t_uint64:
	    /* zero = zero or positive, 1 = negative */
	    break;
	case t_int8:
	    cp_signbit_cp(r->v.obj, v->v.obj, l);
	    break;
	case t_int16:
	    cp_signbit_sp(r->v.obj, v->v.obj, l);
	    break;
	case t_int32:
	    cp_signbit_ip(r->v.obj, v->v.obj, l);
	    break;
	case t_int64:
	    cp_signbit_lp(r->v.obj, v->v.obj, l);
	    break;
	case t_float32:
	    cp_signbit_fp(r->v.obj, v->v.obj, l);
	    break;
	case t_float64:
	    cp_signbit_dp(r->v.obj, v->v.obj, l);
	    break;
	default:
	    cp_signbit_vo(r->v.obj, v->v.obj, l);
	    break;
    }
    v_leave();
}

static void
cp_signbit_cp(c_t *u, c_t *v, eint32_t m)
{
    while (m--)
	*u++ = *v++ < 0;
}

static void
cp_signbit_sp(c_t *u, s_t *v, eint32_t m)
{
    while (m--)
	*u++ = *v++ < 0;
}

static void
cp_signbit_ip(c_t *u, i_t *v, eint32_t m)
{
    while (m--)
	*u++ = *v++ < 0;
}

static void
cp_signbit_lp(c_t *u, l_t *v, eint32_t m)
{
    while (m--)
	*u++ = *v++ < 0;
}

static void
cp_signbit_fp(c_t *u, f_t *v, eint32_t m)
{
    while (m--)
	*u++ = signbit(*v++) != 0;
}

static void
cp_signbit_dp(c_t *u, d_t *v, eint32_t m)
{
    while (m--)
	*u++ = signbit(*v++) != 0;
}

static void
cp_signbit_vo(c_t *u, vo_t *v, eint32_t m)
{
    for (; m; u++, v++, m--) {
	switch (eobject_type(*v)) {
	    case t_void:
		*u = 0;
		break;
	    case t_int:
		*u = get_i(v) < 0;
		break;
	    case t_float:
		*u = signbit(get_d(v)) != 0;
		break;
	    case t_mpz:
		*u = mpz_sgn(get_z(v)) < 0;
		break;
	    case t_mpq:
		*u = mpq_sgn(get_q(v)) < 0;
		break;
	    case t_mpr:
		*u = mpfr_sgn(get_r(v)) < 0;
		break;
	    default:
		eraise_exception(except_not_a_real_number);
	}
    }
}
#endif
